package svc

import (
	"database/sql"

	"mall/common/modelx"
	"mall/service/attachment/rpc/attachmentclient"
	"mall/service/backend/common/gorseclient"
	"mall/service/blog/repository"
	"mall/service/blog/rpc/internal/config"
	"mall/service/user/rpc/userclient"

	"github.com/elastic/go-elasticsearch/v7"
	"github.com/hibiken/asynq"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/zrpc"
)

type ServiceContext struct {
	Config config.Config

	AsynqClient *asynq.Client
	GorseClient gorseclient.GorseClient

	BlogPage repository.BlogPageRepository
	BlogPost repository.BlogPostRepository
	BlogBook repository.BlogBookRepository
	BlogTerm repository.BlogTermRepository // deprecated
	BlogUser repository.BlogUserRepository

	DB         *sql.DB
	Term       repository.TermRepository
	KBEntry    repository.KBEntryRepository
	KBProposal repository.KBProposalRepository
	Page       repository.PageRepository
	Post       repository.PostRepository
	User       repository.UserRepository
	Reaction   repository.ReactionRepository

	EsClient *elasticsearch.Client

	AttachmentRpc attachmentclient.Attachment
	UserRpc       userclient.User
}

func NewServiceContext(c config.Config) *ServiceContext {
	db, err := modelx.NewMysqlConn(c.Mysql.DataSource)
	logx.Must(err)

	esClient, err := newElasticClient(c)
	// logx.Must(err)

	return &ServiceContext{
		Config: c,

		AsynqClient: newAsynqClient(c),
		GorseClient: gorseclient.NewGorseClient(),

		BlogPage: repository.NewBlogPageRepository(c.Mysql.DataSource, c.CacheRedis),
		BlogPost: repository.NewBlogPostRepository(c.Mysql.DataSource, c.CacheRedis),
		BlogBook: repository.NewBlogBookRepository(c.Mysql.DataSource, c.CacheRedis),
		BlogTerm: repository.NewBlogTermRepository(c.Mysql.DataSource, c.CacheRedis),
		BlogUser: repository.NewBlogUserRepository(c.Mysql.DataSource, c.CacheRedis),

		DB:         db,
		Term:       repository.NewTermRepository(db, c.CacheRedis),
		KBEntry:    repository.NewKBEntryRepository(db, c.CacheRedis),
		KBProposal: repository.NewKBProposalRepository(db, c.CacheRedis),
		Page:       repository.NewPageRepository(db, c.CacheRedis),
		Post:       repository.NewPostRepository(db, c.CacheRedis),
		User:       repository.NewUserRepository(db, c.CacheRedis),
		Reaction:   repository.NewReactionRepository(db, c.CacheRedis),

		EsClient: esClient,

		AttachmentRpc: attachmentclient.NewAttachment(zrpc.MustNewClient(c.AttachmentRpc)),
		UserRpc:       userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),
	}
}
